package com.zhao.dota.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.RedisScript;

import java.time.Duration;
import java.util.Collections;
import java.util.Objects;

@Slf4j
public class RedisDistributedLockUtil {

    private static StringRedisTemplate stringRedisTemplate;

    static {
        stringRedisTemplate = SpringUtil.getBean(StringRedisTemplate.class);
    }

    /**
     * * 分布式锁：加锁,放在方法开始处
     *
     * @param key          一般传方法名称
     * @param requestId    请求uuid
     * @param expireSecond 过期时间
     * @return 加锁成功返回true
     */
    public static boolean distributedLock(String key, String requestId, int expireSecond) {
        try {
            String finalKey = "DISLOCK:" + key + "";
            Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(finalKey, requestId, Duration.ofSeconds(expireSecond));
            return Boolean.TRUE.equals(success);
        } catch (Exception ex) {
            log.error("setDistributedLock：加锁失败：" + key + "," + expireSecond + ":" + ex.getMessage(), ex);
            return false;
        }
    }

    /**
     * 分布式锁：解锁
     *
     * @param key
     * @param requestId
     */
    public static boolean distributedUnLock(String key, String requestId) {
        try {
            RedisScript<Long> script = RedisScript.of("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end", Long.TYPE);
            String finalKey = "DISLOCK:" + key;
            Long result = stringRedisTemplate.execute(script, Collections.singletonList(finalKey), requestId);
            return Objects.equals(result, 1L);
        } catch (Exception ex) {
            log.error("setDistributedLock：解锁失败：" + key + "," + requestId + ":" + ex.getMessage(), ex);
        }
        return false;
    }


}
